package com.mathdroid.modules;

import java.io.Serializable;

import com.mathdroid.model.abilities.Ability;

/**
 * Specialization modules have to implement this interface.
 */
public interface IModule extends Cloneable, Serializable {
	
	/**
	 * Do a simulation. Module developers: This method is called repeatedly on 
	 * the same set of data.
	 */
	void simulate();
	
	/**
	 * This method is called before any simulation. Register the abilities in
	 * this method.
	 */
	void before();
	
	/**
	 * This method is called between each simulation. Make your object reusable
	 * in this method. You do not have to reset CoolDowns for abilities that
	 * are managed.
	 */
	void cleanUp();
	
	/**
	 * Check if the ability is executable. For example this can fail if there
	 * is not enough "Rage" or "Energy". 
	 * Do <b>not</b> check the GlobalCoolDown.
	 * Do <b>not</b> check the ability's CoolDown. 
	 * Do not call this method yourself.
	 * @param a Ability to execute.
	 * @return If the ability is executable.
	 */
	boolean isExecutable(final Ability a);
	
	/**
	 * This method is called if an ability is used and passed several checks.
	 * You should implement the resource management, the logging, 
	 * damage/healing done, critical hits, misses etc.
	 * Do not alter the CoolDown.
	 * @param a The ability to execute.
	 * @return The event what happened.
	 */
	SimulationEvent execute(final Ability a);
	
	/**
	 * Create a new instance of the module.
	 * @return New instance.
	 */
	Module getInstance();
}
